package cn.wolfcode.wolf2w.business.repository;


import cn.wolfcode.wolf2w.business.domain.Strategy;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;



/**
 * 是 Elasticsearch（ES）的数据访问层（Repository），专门用于从 ES 的 strategy 索引中执行搜索操作，
 * 将 ES 返回的原始文档数据转换为业务层所需的 Strategy 实体对象，是 “私有知识库检索” 的核心实现类。
 * **/

/// 标记当前类为 数据访问层组件，告知 Spring 这是用于操作数据的类
///（通常与数据库、ES 等存储交互），会被 Spring 扫描并纳入容器管理。
@Repository
public class StrategyRepository {
    /// 定义 ES 索引名称为 strategy（静态常量，方便统一维护），表示所有搜索操作都针对该索引
    /// （ES 中的 “索引” 可理解为关系型数据库中的 “表”，这里存储的是旅行策略数据）。
    private static final String INDEX="strategy";
    /// 注入 ES 高级客户端实例（由 ElasticsearchConfig 类的 restHighLevelClient() 方法创建），
    /// 通过该客户端执行 ES 的搜索请求。
    @Autowired
    private RestHighLevelClient client;
    /**StrategyRepository 是连接业务层与 Elasticsearch 的 “桥梁”，核心功能是：
            → 接收用户查询关键词
            → 构建多字段匹配的 ES 搜索条件
            → 执行搜索
            → 将原始文档数据转换为 Strategy 实体。*/
    public List<Strategy> search(String query, int size) throws IOException {
        ///步骤 1：构建搜索条件（SearchSourceBuilder）
        /**
         * SearchSourceBuilder：ES 提供的搜索条件构建器，用于定义搜索的具体规则（如查询语句、返回数量等）。
         * QueryBuilders.multiMatchQuery(...)：构建 “多字段匹配查询”：
         * 第一个参数 query：用户输入的查询关键词（如 “北京旅行攻略”）；
         * 后续参数 "title", "subTitle", "summary"：指定要搜索的字段（即 ES 文档中的 title（标题）、subTitle（副标题）、summary（摘要）字段）；
         * 作用：在这三个字段中同时搜索包含 query 关键词的文档，提高搜索的全面性。
         * .size(size)：设置返回的最大结果数量（由方法参数 size 指定，如 size=5 表示最多返回 5 条匹配结果）。*/
        SearchSourceBuilder ssb=new SearchSourceBuilder()
                .query(QueryBuilders.multiMatchQuery( query, "title","subTitle","summary"))
                .size(size);
        /// 步骤 2：创建搜索请求（SearchRequest）
        /// SearchRequest(INDEX)：指定要搜索的 ES 索引（即 strategy 索引）；
        /// .source(ssb)：将上一步构建的搜索条件（ssb）设置到请求中，明确 “在哪个索引执行什么条件的搜索”。
        SearchRequest request = new SearchRequest(INDEX).source(ssb);
        /// 步骤 3：执行搜索并获取响应
        /// 通过 RestHighLevelClient 的 search 方法发送搜索请求，参数为 request（搜索请求）
        ///和 RequestOptions.DEFAULT（默认请求配置）；
        /// 返回的 SearchResponse 包含 ES 服务器的搜索结果（匹配的文档列表、得分等信息）。
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        /// 步骤 4：解析响应并转换为 Strategy 实体
        List<Strategy> list = new ArrayList<>();
        /// response.getHits().getHits()：获取所有匹配的文档（SearchHit 数组，每个 SearchHit 代表一个匹配的文档）；
        for (SearchHit hit : response.getHits().getHits()) {
            ///  // 获取ES文档的字段-值映射（原始数据）
        /// 将文档的原始数据转换为 Map<String, Object>（键是字段名，值是字段值）；
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            /// 从映射中提取字段值（转换为字符串）
            String title = sourceAsMap.get("title").toString();
            String subTitle = sourceAsMap.get("subTitle").toString();
            String summary = sourceAsMap.get("summary").toString();
            /// 创建Strategy实体并添加到列表
            Strategy strategy = new Strategy(null, title, subTitle, summary);
            list.add(strategy);
        }
        return list;
    }
}
